#include "ctopbar.h"
#include "ctopbaritem.h"
#include "cpenguin.h"
#include "ctextitem.h"
#include "cbreakitem.h"
#include "caudioitem.h"
#include "cclockitem.h"
#include "cdesktopapp.h"

#include <buola/image/cimage.h>
#include <buola/gui/cconfig.h>
#include <buola/gui/ctoolkit.h>
#include <buola/widgets/ctheme.h>
#include <buola/image/cgc.h>
#include <buola/gui/x11/cfixesregion.h>
#include <buola/image/cpattern.h>
#include <buola/gl/cgltexture.h>
#include <buola/os/cappmenu.h>
#include <buola/widgets/cmenubar.h>

namespace buola { namespace bdesktop {

CTopBar::CTopBar()
    :   mMouseInside(false),
        mPosValid(false),
        mMIMEMenu(nullptr)
{
    SetWMMode(WM_STICKY|WM_NODECORATION);
    SetPaintMode(PAINT_TRANSPARENT);
}

CTopBar::~CTopBar()
{
}

void CTopBar::AddItem(CTopBarItem *pItem)
{
    mItems.push_back(pItem);
    pItem->SetBar(this);
    mPosValid=false;
}

void CTopBar::RemoveItem(CTopBarItem *pItem)
{
}

CTopBarItem *CTopBar::FindItemAt(const CPoint &pPos)
{
    for(int i=0;i<mItems.size();i++)
    {
        if(mItems[i]->GetPos().Contains(pPos))
            return mItems[i];
    }

    return nullptr;
}

void CTopBar::OnCreate()
{
    SetBackNone();
    
    mHeight=21;
    mTotalHeight=30;

    CSize lSize=gui::get_toolkit()->GetRootWindow()->GetSize();

    SetWindowClass(CLASS_DOCK);

    mAltF1.Set(KEY_F1,KEYMOD_ALT,gui::CAccelerator::GLOBAL);

    SetStrut(CRect(0,mHeight,0,0));
    MoveResize(CPoint(0,0),CSize(lSize.x,mTotalHeight));
    SetShape(CRect(0,0,lSize.x,mHeight),gui::SHAPE_INPUT);

    AddItem(new CPenguin);
    mAppMenuItem=new CTextItem(L"Applications");
    mAppMenuItem->sClicked.Connect(&CTopBar::OnAppMenu,this);
    AddItem(mAppMenuItem);
    mPlacesMenuItem=new CTextItem(L"Places");
    mPlacesMenuItem->sClicked.Connect(&CTopBar::OnPlacesMenu,this);
    AddItem(mPlacesMenuItem);
    AddItem(new CTextItem(L"Windows"));
    AddItem(new CTextItem(L"Tasks"));
    AddItem(new CBreakItem);
    AddItem(new CAudioItem);
    AddItem(new CClockItem);
}

void CTopBar::OnButtonDown(gui::CMouseEvent *pE)
{
    CTopBarItem *lItem=FindItemAt(pE->mPoint);
        
    if(lItem)
        lItem->OnClick(pE);
}

void CTopBar::OnMouseMove(gui::CMouseEvent *pE)
{
}

void CTopBar::OnMouseOut(gui::CMouseEvent*)
{
}

void CTopBar::OnPreExpose()
{
    if(!mPosValid)
    {
        double lX=mRect.l;
        int i=0;
        for(i=0;i<mItems.size();i++)
        {
            if(mItems[i]->IsBreak())
            {
                mItems[i]->SetPos(CRect(nUndefined));
                break;
            }
            double lW=mItems[i]->GetWidth();
            
            mItems[i]->SetPos(CRect(lX,mRect.t+1,lX+lW,mRect.t+mHeight));
            lX+=lW;
        }
        
        lX=mRect.r;
        
        for(int j=mItems.size()-1;j>i;j--)
        {
            double lW=mItems[j]->GetWidth();
            
            lX-=lW;
            mItems[j]->SetPos(CRect(lX,mRect.t+1,lX+lW,mRect.t+mHeight));
        }
    
        mPosValid=true;
    }
}

void CTopBar::OnExpose(gui::CExposeEvent *pE)
{
    CGC *lGC=pE->mGC;

    lGC->SetOperator(CGC::OP_SRC);

    lGC->SetLineWidth(1.0);
//    lGC->SetSourceColor(CColor(1.0,1.0,1.0,0.9));
    lGC->SetSourceColor(CColor(0.4,0.4,0.4,0.9));
    lGC->MoveTo(CPoint(0,0.5));
    lGC->LineTo(CPoint(mRect.r,0.5));
    lGC->StrokePath();

    PPattern lBasePattern=lGC->NewPattern(CPoint(0,1),CPoint(0,mHeight));
//    lBasePattern->AddColorStop(CColor(1.0,1.0,1.0,0.8),0.00);
//    lBasePattern->AddColorStop(CColor(0.8,0.8,0.8,0.7),1.00);
    lBasePattern->AddColorStop(CColor(0.3,0.3,0.3,0.9),0.00);
    lBasePattern->AddColorStop(CColor(0.0,0.0,0.0,0.8),1.00);

    lGC->SetSourcePattern(lBasePattern);
//  lGC->SetSourceColor(CColor(1,1,1,0.5));
    lGC->Rectangle(CPoint(0,1),CSize(mRect.w(),mHeight-1));
    lGC->FillPath();

    lGC->SetOperator(CGC::OP_SRC);
    PPattern lShadowPattern=lGC->NewPattern(CPoint(0,mHeight),CPoint(0,mTotalHeight));
    lShadowPattern->AddColorStop(CColor(0,0,0,0.4),0.0);
    lShadowPattern->AddColorStop(CColor(0,0,0,0.0),1.0);
    lGC->SetSourcePattern(lShadowPattern);
    lGC->Rectangle(CPoint(0,mHeight),CSize(mRect.w(),mTotalHeight-mHeight));
    lGC->FillPath();
    lGC->Rectangle(CPoint(0,mHeight),CSize(mRect.w(),mTotalHeight-mHeight));
    lGC->FillPath();

    lGC->SetOperator(CGC::OP_OVER);
    
    for(int i=0;i<mItems.size();i++)
    {
        mItems[i]->Draw(lGC);
    }
}

void CTopBar::OnSize(gui::CGeometryEvent*)
{
}

void CTopBar::OnKeyDown(gui::CKeyEvent *pE)
{
    if(pE->mMods==KEYMOD_ALT)
    {
        if(pE->mKey==KEY_F1)
        {
        }
    }
}

void CTopBar::OnAppMenu()
{
    if(!mMIMEMenu)
    {
        mMIMEMenu=os::get_default_app_menu();
    }
    if(!mAppMenu)
    {
        mAppMenu=new gui::CMenu;
        mAppMenu->FillWith(mMIMEMenu);
    }
    gui::CMenuBar *lMenuBar=new gui::CMenuBar;
    lMenuBar->SetIconSize(gui::CIcon::MEDIUM);
    lMenuBar->SetStyleBit(gui::CMenuBar::STYLE_COMMENT);
    lMenuBar->CreatePopup(this,mAppMenu,CPoint(mAppMenuItem->GetPos().l,
                            mAppMenuItem->GetPos().b));
    lMenuBar->Show();
}

void CTopBar::OnPlacesMenu()
{
    gui::PMenu lPlacesMenu=new gui::CMenu;
    gDesktopApp->GetVolumeManager()->FillPlacesMenu(lPlacesMenu);
    
    gui::CMenuBar *lMenuBar=new gui::CMenuBar;
    lMenuBar->SetIconSize(gui::CIcon::MEDIUM);
    lMenuBar->SetStyleBit(gui::CMenuBar::STYLE_COMMENT);
    lMenuBar->CreatePopup(this,lPlacesMenu,CPoint(mPlacesMenuItem->GetPos().l,
                            mPlacesMenuItem->GetPos().b));
    lMenuBar->Show();
}

/*namespace bdesktop*/ } /*namespace buola*/ }
